package com.ruoyi.system.service.impl;

import java.util.List;

import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.system.business.QsTagImportBusinessService;
import com.ruoyi.system.business.vo.DrInfoImport;
import com.ruoyi.system.domain.*;
import com.ruoyi.system.mapper.DrtypemodeMapper;
import com.ruoyi.system.mapper.RegMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.Map;

import com.ruoyi.common.utils.StringUtils;
import org.springframework.transaction.annotation.Transactional;
import com.ruoyi.system.mapper.DrinfoMapper;
import com.ruoyi.system.service.IDrinfoService;

import javax.annotation.Resource;

/**
 * 设备信息管理Service业务层处理
 * 
 * @author yaozh
 * @date 2024-03-01
 */
@Service
public class DrinfoServiceImpl implements IDrinfoService 
{
    private static final Logger log = LoggerFactory.getLogger(DrinfoServiceImpl.class);
    @Resource
    private DrinfoMapper drinfoMapper;
    @Resource
    private DrtypemodeMapper drtypemodeMapper;
    @Resource
    private RegMapper regMapper;
    @Resource
    private QsTagImportBusinessService qsTagImportBusinessService;

    /**
     * 查询设备信息管理
     * 
     * @param drid 设备信息管理主键
     * @return 设备信息管理
     */
    @Override
    public Drinfo selectDrinfoByDrid(Long drid,String dbName)
    {
        return drinfoMapper.selectDrinfoByDrid(drid,dbName);
    }

    public List<Drinfo> findAllDrinfo(String dbName){
        return drinfoMapper.findAllDrinfo(dbName);
    }

    @Transactional
    @Override
    public int saveDevice(String dbName, Drinfo drinfo, Map<String,String> qsTagMap){
        if(drinfo.getDrtypeid() == null || drinfo.getDrtypeid() < 1){
            throw new IllegalArgumentException("请选择设备类型");
        }
        int rows=0;
        try {
            rows = insertDevice(dbName,drinfo,qsTagMap);
        } catch (Exception e) {
            e.printStackTrace();
            throw new ServiceException("保存失败");
        }
        return rows;
    }

    private int insertDevice(String dbName, Drinfo drinfo, Map<String,String> qsTagMap){
        int rows = drinfoMapper.insertObject(dbName,drinfo);//根据dbName（项目）保存/添加 设备信息
        List<Drtypemode> list = drtypemodeMapper.findObject(dbName, drinfo.getDrtypeid(), null, null);//根据dbName（项目）、子系统/设备类型ID 返回设备类型模板，涉及表(drtypemode、drtypeinfo、sub、alarmtype)
        List<Drtypemode> newList = new ArrayList<>();
        if (list != null && list.size() != 0) {
            for (Drtypemode drtypemode : list) {
                String key = drinfo.getDrcode() + drtypemode.getRegName();
                String value = qsTagMap.get(key);
                if(org.springframework.util.StringUtils.hasLength(value)){
                    drtypemode.setTypemodeid(null);
                    newList.add(drtypemode);
                }
            }
            if(newList.size() > 0){
                regMapper.insertObjectByDrtypemodes(dbName,drinfo.getDrid(),newList);//根据dbName（项目）、设备ID、设备类型模板列表 批量保存到变量表，
            }else{
                System.out.println("列表空：" + drinfo.getDrname());
            }
        }
        return rows;
    }

    private int updateDeviceName(String dbName, Drinfo oldDrInfo, Map<String,String> qsTagMap){
        int rows = drinfoMapper.updateObject(dbName,oldDrInfo);
        List<Drtypemode> list = drtypemodeMapper.findObject(dbName, oldDrInfo.getDrtypeid(), null, null);//根据dbName（项目）、子系统/设备类型ID 返回设备类型模板，涉及表(drtypemode、drtypeinfo、sub、alarmtype)
        List<Drtypemode> newList = new ArrayList<>();
        if (list != null && list.size() != 0) {
            List<String> regNameList = regMapper.findAllRegNameByDrId(dbName,oldDrInfo.getDrid());
            for (Drtypemode drtypemode : list) {
                String key = oldDrInfo.getDrcode() + drtypemode.getRegName();
                String value = qsTagMap.get(key);
                if(org.springframework.util.StringUtils.hasLength(value)){
                    drtypemode.setTypemodeid(null);
                    newList.add(drtypemode);
                }
            }
            if(newList.size() > 0){
                if(regNameList == null || regNameList.size() == 0){
                    regMapper.insertObjectByDrtypemodes(dbName,oldDrInfo.getDrid(),newList);//根据dbName（项目）、设备ID、设备类型模板列表 批量保存到变量表，
                }else{
                    if(newList.size() == regNameList.size()){
                        //更新。但因没什么变化，不用更新。
                    }else if(newList.size() > regNameList.size()){
                        //插入部分
                        List<Drtypemode> tempNewList = new ArrayList<>();
                        for(Drtypemode drTypeMode : newList){
                            String name = drTypeMode.getRegName();
                            boolean isFind = false;
                            for(String oldName : regNameList){
                                if(org.springframework.util.StringUtils.hasLength(name) && name.equals(oldName)){
                                    isFind = true;
                                }
                            }
                            if(!isFind){
                                tempNewList.add(drTypeMode);
                            }
                        }
                        if(tempNewList.size() > 0){
                            regMapper.insertObjectByDrtypemodes(dbName,oldDrInfo.getDrid(),tempNewList);//根据dbName（项目）、设备ID、设备类型模板列表 批量保存到变量表，
                        }
                    }else{
                        //reg表有多余的，隐藏掉多余的
                        for(String oldName : regNameList){
                            boolean isFind = false;
                            for(Drtypemode drTypeMode : newList){
                                String name = drTypeMode.getRegName();
                                if(org.springframework.util.StringUtils.hasLength(name) && name.equals(oldName)){
                                    isFind = true;
                                }
                            }
                            if(!isFind){
                                //隐藏
                                regMapper.updateIsThreeDShowByDrIdAndRegName(dbName,oldDrInfo.getDrid(),oldName,0);
                            }
                        }
                    }
                }
            }else{
                System.out.println("列表空：" + oldDrInfo.getDrname());
            }
        }
        return rows;
    }

    @Transactional
    @Override
    public int saveOrUpdateDevice(String dbName, Drinfo drinfo, Map<String,String> qsTagMap,List<Drinfo> oldList){
        if(drinfo.getDrtypeid() == null || drinfo.getDrtypeid() < 1){
            throw new IllegalArgumentException("请选择设备类型");
        }
        int rows=0;
        try{
            boolean find = false;
            Drinfo tempOldDrInfo = null;
            for(Drinfo tempDrInfo : oldList){
                String drCode = tempDrInfo.getDrcode();
                Long drTypeId = tempDrInfo.getDrtypeid();
                if(drTypeId.intValue() == drinfo.getDrtypeid().intValue() && org.springframework.util.StringUtils.hasLength(drCode) && drCode.equals(drinfo.getDrcode())){
                    find = true;
                    tempOldDrInfo = tempDrInfo;
                    break;
                }
            }
            if(find){
                //更新设备信息
                tempOldDrInfo.setDrname(drinfo.getDrname());
                rows = updateDeviceName(dbName,tempOldDrInfo,qsTagMap);//仅仅更新设备的名称，其它字段保持不变
            }else{
                //插入
                rows = insertDevice(dbName,drinfo,qsTagMap);
            }
        }catch (Exception e){
            e.printStackTrace();
            throw new ServiceException("保存或更新失败");
        }
        return rows;
    }

    @Transactional
    @Override
    public int saveVirtualDevice(String dbName, Drinfo drInfo, List<Drinfo> oldList,List<RegGroup> groupList) {
        if(drInfo.getDrtypeid()==null||drInfo.getDrtypeid()<1){
            throw new IllegalArgumentException("请选择设备类型");
        }
        int rows=0;
        try {
            long regGroupId = 2;
            for(RegGroup regGroup : groupList){
                if(regGroup.getGroupName() != null && regGroup.getGroupName().equals("电表参数")){
                    regGroupId = regGroup.getId();
                    break;
                }
            }
            List<Drtypemode> list = new ArrayList<>();
            Drtypemode drtypemode = new Drtypemode();
            drtypemode.setTagTime("5");
            drtypemode.setRegName(drInfo.getDrtypename());//属性名
            drtypemode.setRegType("5");//值类型：1、离散型(Bool)，2、长整型(DINT)，3、模拟型(Int)，4、字符型(WORD)，5、浮点型(Real)，6、64位浮点型(LReal)，7、32位无符号整型(DWORD)）
            drtypemode.setRegUnits(drInfo.getAreaName());
            drtypemode.setRegReadwrite("1");//只读
            drtypemode.setRegGroupId(regGroupId);//分组
            drtypemode.setRegListshowlevel(1L);
            drtypemode.setIsThreeDShow(1);
            drtypemode.setIshistory("1");
            drtypemode.setIsenergy("1");
            list.add(drtypemode);

            String regName = drInfo.getDrtypename();

            //去掉辅助的变量值，上面已经用完
            drInfo.setDrtypename(null);
            drInfo.setAreaName(null);

            //检查
            boolean find = false;
            Drinfo tempOldDrInfo = null;
            for(Drinfo tempDrInfo : oldList){
                String drCode = tempDrInfo.getDrcode();
                Long drTypeId = tempDrInfo.getDrtypeid();
                if(drTypeId.intValue() == drInfo.getDrtypeid().intValue() && org.springframework.util.StringUtils.hasLength(drCode) && drCode.equals(drInfo.getDrcode())){
                    find = true;
                    tempOldDrInfo = tempDrInfo;
                    break;
                }
            }
            if(find){
                //更新设备信息
                tempOldDrInfo.setDrname(drInfo.getDrname());
                rows = drinfoMapper.updateObject(dbName,tempOldDrInfo);
                List<String> regNameList = regMapper.findAllRegNameByDrId(dbName,tempOldDrInfo.getDrid());
                boolean isFind = false;
                if(regNameList != null && regNameList.size() > 0){
                    for(String oldName : regNameList){
                        if(org.springframework.util.StringUtils.hasLength(regName) && regName.equals(oldName)){
                            isFind = true;
                        }
                    }
                }
                if(!isFind){
                    //插入
                    regMapper.insertObjectByDrtypemodes(dbName,drInfo.getDrid(),list);//
                }else{
                    //更新，很可能是要展示
                    regMapper.updateIsThreeDShowByDrIdAndRegName(dbName,drInfo.getDrid(),regName,1);//展示
                }
            }else{
                //插入
                rows=drinfoMapper.insertObject(dbName,drInfo);//
                if(rows > 0){
                    oldList.add(drInfo);
                }
                regMapper.insertObjectByDrtypemodes(dbName,drInfo.getDrid(),list);//虚拟变量只有一个 电量 属性
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new ServiceException("保存失败");
        }
        return rows;
    }

    /**
     * 查询设备信息管理列表
     * 
     * @param drinfo 设备信息管理
     * @return 设备信息管理
     */
    @Override
    public List<Drinfo> selectDrinfoList(Drinfo drinfo,String dbName)
    {
        return drinfoMapper.selectDrinfoList(drinfo,dbName);
    }

    @Override
    public List<Drinfo> selectByDrTypeId(Long drTypeId,String dbName){
        return drinfoMapper.selectByDrTypeId(drTypeId,dbName);
    }

    /**
     * 新增设备信息管理
     * 
     * @param drinfo 设备信息管理
     * @return 结果
     */
    @Transactional
    @Override
    public int insertDrinfo(Drinfo drinfo,String dbName)
    {
        int rows = drinfoMapper.insertDrinfo(drinfo,dbName);
        insertReg(drinfo,dbName);
        return rows;
    }

    /**
     * 修改设备信息管理
     * 
     * @param drinfo 设备信息管理
     * @return 结果
     */
    @Transactional
    @Override
    public int updateDrinfo(Drinfo drinfo,String dbName)
    {
        drinfoMapper.deleteRegByDrId(drinfo.getDrid(),dbName);
        insertReg(drinfo,dbName);
        return drinfoMapper.updateDrinfo(drinfo,dbName);
    }

    /**
     * 批量删除设备信息管理
     * 
     * @param drids 需要删除的设备信息管理主键
     * @return 结果
     */
    @Transactional
    @Override
    public int deleteDrinfoByDrids(Long[] drids,String dbName)
    {
        drinfoMapper.deleteRegByDrIds(drids,dbName);
        return drinfoMapper.deleteDrinfoByDrids(drids,dbName);
    }

    /**
     * 删除设备信息管理信息
     * 
     * @param drid 设备信息管理主键
     * @return 结果
     */
    @Transactional
    @Override
    public int deleteDrinfoByDrid(Long drid,String dbName)
    {
        drinfoMapper.deleteRegByDrId(drid,dbName);
        return drinfoMapper.deleteDrinfoByDrid(drid,dbName);
    }

    /**
     * 新增属性变量管理信息
     * 
     * @param drinfo 设备信息管理对象
     */
    public void insertReg(Drinfo drinfo,String dbName)
    {
        List<Reg> regList = drinfo.getRegList();
        Long drid = drinfo.getDrid();
        if (StringUtils.isNotNull(regList))
        {
            List<Reg> list = new ArrayList<Reg>();
            for (Reg reg : regList)
            {
                reg.setDrId(drid);
                list.add(reg);
            }
            if (list.size() > 0)
            {
                drinfoMapper.batchReg(list,dbName);
            }
        }
    }

    @Override
    public String importDrInfo(List<Drinfo> drInfoList, Boolean isUpdateSupport, String operaName, String dbName){
        if (com.ruoyi.common.utils.StringUtils.isNull(drInfoList) || drInfoList.size() == 0)
        {
            throw new ServiceException("导入项目设备列表数据不能为空！");
        }
        int successNum = 0;
        int failureNum = 0;
        StringBuilder successMsg = new StringBuilder();
        StringBuilder failureMsg = new StringBuilder();
        for (Drinfo drInfo : drInfoList)
        {
            try{
                // 验证是否存在
                String drCode = drInfo.getDrcode();
                Drinfo tempDrInfo = drinfoMapper.selectDrinfoByDrCode(drCode,dbName);
                if (tempDrInfo == null)
                {
                    drInfo.setCreateBy(operaName);
                    drinfoMapper.insertDrinfo(drInfo,dbName);
                    successNum++;
                    successMsg.append("<br/>" + successNum + "、设备名称 " + drInfo.getDrname() + "、设备编码 " + drInfo.getDrcode() + " 导入成功");
                }
                else if (isUpdateSupport)
                {
                    drInfo.setDrid(tempDrInfo.getDrid());
                    drInfo.setUpdateBy(operaName);
                    drinfoMapper.updateDrinfo(drInfo,dbName);
                    successNum++;
                    successMsg.append("<br/>" + successNum + "、设备名称 " + drInfo.getDrname() + "、设备编码 " + drInfo.getDrcode() + " 更新成功");
                }
                else
                {
                    failureNum++;
                    failureMsg.append("<br/>" + failureNum + "、设备名称 " + drInfo.getDrname() + "、设备编码 " + drInfo.getDrcode() + " 已存在");
                }
            }
            catch (Exception e)
            {
                failureNum++;
                String msg = "<br/>" + failureNum + "、设备名称 " + drInfo.getDrname() + "、设备编码 " + drInfo.getDrcode() + " 导入失败：";
                failureMsg.append(msg + e.getMessage());
                log.error(msg, e);
            }
        }

        if (failureNum > 0)
        {
            failureMsg.insert(0, "很抱歉，导入失败！共 " + failureNum + " 条数据格式不正确，错误如下：");
            throw new ServiceException(failureMsg.toString());
        }
        else
        {
            successMsg.insert(0, "恭喜您，数据已全部导入成功！共 " + successNum + " 条，数据如下：");
        }
        return successMsg.toString();
    }

    @Override
    public String importDrInfoInit(List<DrInfoImport> drInfoList, Boolean isUpdateSupport, String operaName, String dbName){
        if (com.ruoyi.common.utils.StringUtils.isNull(drInfoList) || drInfoList.size() == 0)
        {
            throw new ServiceException("导入项目设备列表数据不能为空！");
        }
        int successNum = 0;
        int failureNum = 0;
        StringBuilder successMsg = new StringBuilder();
        StringBuilder failureMsg = new StringBuilder();
        //导入处理
        AjaxResult ajaxResult = qsTagImportBusinessService.importEquipmentList(dbName,drInfoList);

        if (ajaxResult != null && !ajaxResult.isSuccess())
        {
            failureMsg.append("<br/>" + ajaxResult.toString());
            failureMsg.insert(0, "很抱歉，导入失败！错误如下：");
            throw new ServiceException(failureMsg.toString());
        }
        else
        {
            successMsg.append("<br/>" + ajaxResult.toString());
            successMsg.insert(0, "恭喜您，数据已全部导入成功！结果如下：");
        }
        return successMsg.toString();
    }
}
